package com.wechat.websocket.netty;

import com.wechat.websocket.ChannelContextUtils;
import io.netty.channel.Channel;
import io.netty.channel.ChannelDuplexHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
import io.netty.util.Attribute;
import io.netty.util.AttributeKey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.annotation.Resource;

/**
 * @Description ws 处理超时心跳
 */
public class HandlerHeartBeat extends ChannelDuplexHandler {
    private static final Logger logger = LoggerFactory.getLogger(HandlerHeartBeat.class);

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        if (evt instanceof IdleStateEvent) {//如果心跳超时
            IdleStateEvent e = (IdleStateEvent) evt;
            if (e.state() == IdleState.READER_IDLE) {//读超时（客户端长时间未发送信息）
                Channel channel = ctx.channel();
                String userId =(String) channel.attr(AttributeKey.newInstance(channel.id().toString())).get();
                logger.info("用户{}心跳超时",userId);
                ctx.close();//关闭连接
            } else if (e.state() == IdleState.WRITER_IDLE) {//写超时（服务端长时间未发送信息）
                ctx.writeAndFlush("heart");//发送心跳包，维持连接
            }
        }
    }
}
/*
userEventTriggered用于处理自定义事件的方法

ChannelDuplexHandler：继承了ChannelInboundHandlerAdapter和ChannelOutboundHandlerAdapter，允许同时处理入站与出站事件
                      专门用于处理用户自定义事件
ChannelHandlerContext ctx, Object evt：
ctx---Netty 框架在调用处理器方法时自动传入，包含了当前 ChannelHandler 的上下文信息
evt---由之前添加到 ChannelPipeline 中的 IdleStateHandler 产生并传播
当连接空闲超时时，IdleStateHandler 会创建 IdleStateEvent 事件
该事件通过 ChannelPipeline 向后传播到 HandlerHeartBeat
 */